/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package thrift

import (
	"log"
	"os"
)

// ServerOptions is options needed to run a thrift server
type ServerOptions struct {
	quit chan struct{}
	log  *log.Logger

	serverTransport        ServerTransport
	inputTransportFactory  TransportFactory
	outputTransportFactory TransportFactory
	inputProtocolFactory   ProtocolFactory
	outputProtocolFactory  ProtocolFactory
}

// TransportFactories sets both input and output transport factories
func TransportFactories(factory TransportFactory) func(*ServerOptions) {
	return func(server *ServerOptions) {
		server.inputTransportFactory = factory
		server.outputTransportFactory = factory
	}
}

// InputTransportFactory sets the input transport factory
func InputTransportFactory(factory TransportFactory) func(*ServerOptions) {
	return func(server *ServerOptions) {
		server.inputTransportFactory = factory
	}
}

// OutputTransportFactory sets the output transport factory
func OutputTransportFactory(factory TransportFactory) func(*ServerOptions) {
	return func(server *ServerOptions) {
		server.outputTransportFactory = factory
	}
}

// ProtocolFactories sets both input and output protocol factories
func ProtocolFactories(factory ProtocolFactory) func(*ServerOptions) {
	return func(server *ServerOptions) {
		server.inputProtocolFactory = factory
		server.outputProtocolFactory = factory
	}
}

// InputProtocolFactory sets the input protocol factory
func InputProtocolFactory(factory ProtocolFactory) func(*ServerOptions) {
	return func(server *ServerOptions) {
		server.inputProtocolFactory = factory
	}
}

// OutputProtocolFactory sets the output protocol factory
func OutputProtocolFactory(factory ProtocolFactory) func(*ServerOptions) {
	return func(server *ServerOptions) {
		server.outputProtocolFactory = factory
	}
}

// Logger sets the logger used for the server
func Logger(log *log.Logger) func(*ServerOptions) {
	return func(server *ServerOptions) {
		server.log = log
	}
}

func defaultServerOptions(serverTransport ServerTransport) *ServerOptions {
	return &ServerOptions{
		serverTransport:        serverTransport,
		inputTransportFactory:  NewTransportFactory(),
		outputTransportFactory: NewTransportFactory(),
		inputProtocolFactory:   NewBinaryProtocolFactoryDefault(),
		outputProtocolFactory:  NewBinaryProtocolFactoryDefault(),
		quit: make(chan struct{}, 1),
		log:  log.New(os.Stderr, "", log.LstdFlags),
	}
}
